package com.example.yijian;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.example.yijian.base.MSLiveWindow;
import com.example.yijian.utils.ScreenUtils;
import com.example.yijian.utils.TimelineUtil;
import com.example.yijian.utils.asset.NvAsset;
import com.example.yijian.utils.datainfo.TimelineData;
import com.meicam.sdk.NvsLiveWindow;
import com.meicam.sdk.NvsStreamingContext;
import com.meicam.sdk.NvsTimeline;

public class PreviewActivity extends AppCompatActivity {
    private static final long BASE_VALUE = 100000;

    private RelativeLayout mPlayerLayout;
    private MSLiveWindow mLiveWindow;
    private RelativeLayout mPlayButton;
    private ImageView mPlayImage;
    private TextView mCurrentDuration;
    private TextView mTotalDuration;
    private SeekBar mSeekBar;
    private RelativeLayout mCancel;


    private NvsStreamingContext mStreamingContext;
    private NvsTimeline mTimeline;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_preview);
        initView();
        initData();
    }

    @Override
    protected void onResume() {
        super.onResume();
        connectTimelineWithLiveWindow();
        seekTimeline(0, 0);
    }

    private void initData() {
        mStreamingContext = NvsStreamingContext.getInstance();
        mTimeline = TimelineUtil.createTimeline();
        if (mTimeline == null) {
            return;
        }
        seekTimeline(mStreamingContext.getTimelineCurrentPosition(mTimeline), 0);
        setLiveWindowRatio(TimelineData.instance().getMakeRatio());
        updateTotalDurationText();
        mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    long currentTimeStamp = progress * BASE_VALUE;
                    seekTimeline(currentTimeStamp, 0);
                    updateCurPlayTime(progress * BASE_VALUE);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });
        mPlayButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (getCurrentEngineState() == NvsStreamingContext.STREAMING_ENGINE_STATE_PLAYBACK) {
                    stopEngine();
                } else {
                    if (mTimeline == null) {
                        return;
                    }
                    //播放进度，如果是动画的页面，播放的可能是片段或者是整体，指定了播放的范围
                    long startTime = mStreamingContext.getTimelineCurrentPosition(mTimeline);
                    long endTime = mTimeline.getDuration();
                    playVideo(startTime, endTime);
                }
            }
        });
        mCancel.setOnClickListener(v -> finish());
    }

    private int getCurrentEngineState() {
        return mStreamingContext.getStreamingEngineState();
    }

    private void initView() {
        mPlayerLayout = (RelativeLayout) findViewById(R.id.video_layout);
        mLiveWindow = findViewById(R.id.liveWindow);
        mPlayButton = findViewById(R.id.playLayout);
        mPlayImage = findViewById(R.id.playImage);
        mCurrentDuration = findViewById(R.id.currentPlaytime);
        mSeekBar = findViewById(R.id.play_seekBar);
        mTotalDuration = findViewById(R.id.totalDuration);
        mCancel = findViewById(R.id.rl_cancel);
    }

    /*
     * 连接时间线跟liveWindow
     * Connect timeline with liveWindow
     * */
    public void connectTimelineWithLiveWindow() {
        if (mStreamingContext == null || mTimeline == null || mLiveWindow == null)
            return;
        mStreamingContext.setPlaybackCallback(new NvsStreamingContext.PlaybackCallback() {
            @Override
            public void onPlaybackPreloadingCompletion(NvsTimeline nvsTimeline) {

            }

            @Override
            public void onPlaybackStopped(NvsTimeline nvsTimeline) {
            }

            @Override
            public void onPlaybackEOF(NvsTimeline nvsTimeline) {
                if (nvsTimeline.getDuration() - mStreamingContext.getTimelineCurrentPosition(mTimeline) <= 40000) {
                    updateCurPlayTime(0);
                    seekTimeline(0, 0);
                }
            }
        });

        mStreamingContext.setPlaybackCallback2(new NvsStreamingContext.PlaybackCallback2() {
            @Override
            public void onPlaybackTimelinePosition(NvsTimeline nvsTimeline, long cur_position) {
                updateCurPlayTime(cur_position);
            }
        });

        mStreamingContext.setStreamingEngineCallback(new NvsStreamingContext.StreamingEngineCallback() {
            @Override
            public void onStreamingEngineStateChanged(int i) {
                if (i == NvsStreamingContext.STREAMING_ENGINE_STATE_PLAYBACK) {
                    mPlayImage.setBackgroundResource(R.mipmap.icon_play);
                } else {
                    mPlayImage.setBackgroundResource(R.mipmap.icon_pause);
                }
            }

            @Override
            public void onFirstVideoFramePresented(NvsTimeline nvsTimeline) {

            }
        });
        mStreamingContext.connectTimelineWithLiveWindow(mTimeline, mLiveWindow);
    }

    public void seekTimeline(long timestamp, int seekShowMode) {
        mStreamingContext.seekTimeline(mTimeline, timestamp,
                NvsStreamingContext.VIDEO_PREVIEW_SIZEMODE_LIVEWINDOW_SIZE, seekShowMode | NvsStreamingContext.STREAMING_ENGINE_SEEK_FLAG_BUDDY_HOST_VIDEO_FRAME);
    }

    public void updateCurPlayTime(long time) {
        mCurrentDuration.setText(formatTimeStrWithUs(time));
        mSeekBar.setProgress((int) (time / BASE_VALUE));
    }

    public void updateTotalDurationText() {
        if (mTimeline != null) {
            mTotalDuration.setText(formatTimeStrWithUs(mTimeline.getDuration()));
            mSeekBar.setMax((int) (mTimeline.getDuration() / BASE_VALUE));
        }
    }

    /*
     * 播放视频
     * Play video
     * */
    public void playVideo(long startTime, long endTime) {
        mStreamingContext.playbackTimeline(mTimeline, startTime, endTime, NvsStreamingContext.VIDEO_PREVIEW_SIZEMODE_LIVEWINDOW_SIZE, true, NvsStreamingContext.STREAMING_ENGINE_PLAYBACK_FLAG_BUDDY_HOST_VIDEO_FRAME);

    }

    //formate time
    private String formatTimeStrWithUs(long us) {
        int second = (int) (us / 1000000.0);
        int hh = second / 3600;
        int mm = second % 3600 / 60;
        int ss = second % 60;
        return hh > 0 ? String.format("%02d:%02d:%02d", hh, mm, ss) : String.format("%02d:%02d", mm, ss);
    }

    private void setLiveWindowRatio(int ratio) {
        ViewGroup.LayoutParams layoutParams = mPlayerLayout.getLayoutParams();
        int statusHeight = ScreenUtils.getStatusBarHeight(this);
        int screenWidth = ScreenUtils.getScreenWidth(this);
        int screenHeight = ScreenUtils.getScreenHeight(this);
        int newHeight = screenHeight - statusHeight;
        switch (ratio) {
            case NvAsset.AspectRatio_16v9: // 16:9
                layoutParams.width = screenWidth;
                layoutParams.height = (int) (screenWidth * 9.0 / 16);
                break;
            case NvAsset.AspectRatio_1v1: //1:1
                layoutParams.width = screenWidth;
                layoutParams.height = screenWidth;
                if (newHeight < screenWidth) {
                    layoutParams.width = newHeight;
                    layoutParams.height = newHeight;
                }
                break;
            case NvAsset.AspectRatio_9v16: //9:16
                layoutParams.width = (int) (newHeight * 9.0 / 16);
                layoutParams.height = newHeight;
                break;
            case NvAsset.AspectRatio_3v4: // 3:4
                layoutParams.width = (int) (newHeight * 3.0 / 4);
                layoutParams.height = newHeight;
                break;
            case NvAsset.AspectRatio_4v3: //4:3
                layoutParams.width = screenWidth;
                layoutParams.height = (int) (screenWidth * 3.0 / 4);
                break;
            case NvAsset.AspectRatio_21v9: //21:9
                layoutParams.width = screenWidth;
                layoutParams.height = (int) (screenWidth * 9.0 / 21);
                break;
            case NvAsset.AspectRatio_9v21: //9:21
                layoutParams.width = (int) (newHeight * 9.0 / 21);
                layoutParams.height = newHeight;
                break;
            case NvAsset.AspectRatio_18v9: //18:9
                layoutParams.width = screenWidth;
                layoutParams.height = (int) (screenWidth * 9.0 / 18);
                break;
            case NvAsset.AspectRatio_9v18: //9:18
                layoutParams.width = (int) (newHeight * 9.0 / 18);
                layoutParams.height = newHeight;
                break;
            default: // 16:9
                layoutParams.width = screenWidth;
                layoutParams.height = (int) (screenWidth * 9.0 / 16);
                break;
        }
        mPlayerLayout.setLayoutParams(layoutParams);
        mLiveWindow.setFillMode(NvsLiveWindow.FILLMODE_PRESERVEASPECTFIT);
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopEngine();
    }

    /*
     * 停止引擎
     * Stop the engine
     * */
    public void stopEngine() {
        //如果生成的时候不要调用stop，防止切换到后台被停止
        if (getCurrentEngineState() != NvsStreamingContext.STREAMING_ENGINE_STATE_COMPILE) {
            if (mStreamingContext != null) {
                mStreamingContext.stop();
            }
        }
    }
}